﻿//Created by Action Script Viewer - http://www.buraks.com/asv
package Classes.sim {
    import Engine.Classes.*;
    import Engine.Managers.*;
    import flash.display.*;
    import flash.geom.*;
    import Engine.Helpers.*;
    import flash.utils.*;
    import Classes.*;
    import __AS3__.vec.*;
    import Engine.*;
    import com.adobe.utils.*;

    public class RoadManager implements IGameWorldStateObserver {

        public static const PATH_ROAD_ONLY:int = 0;
        public static const PATH_TO_FRONT_ENTRANCE:int = 1;
        public static const PATH_FULL:int = 2;
        public static const SIDEWALK_WIDTH:Number = 1;
        public static const SIDEWALK_HEIGHT:Number = 1;
        public static const ROAD_WIDTH:Number = 3;
        public static const ROAD_HEIGHT:Number = 3;

        protected const MIN_RANDOM_ROAD_GRAPH_LEN:int = 5;

        protected var m_endpointInfluence:int;
        protected var m_roadSize:Vector3;
        protected var m_sidewalkSize:Vector3;
        protected var m_roads:Array;
        protected var m_graphs:Array;
        protected var m_world:GameWorld;
        protected var m_x:int;
        protected var m_y:int;
        protected var m_width:int;
        protected var m_height:int;
        protected var m_roadOverlay:Sprite;
        protected var m_dbgShape:Shape;
        protected var m_isStatSent:Boolean = false;

        public function RoadManager(_arg1:GameWorld){
            this.m_world = _arg1;
            var _local2:Rectangle = this.m_world.getWorldRect();
            this.m_x = _local2.x;
            this.m_y = _local2.y;
            this.m_width = _local2.width;
            this.m_height = _local2.height;
            this.m_endpointInfluence = Global.gameSettings.getAttribute("carPathEndpointInfluence");
            _arg1.addObserver(this);
        }
        public function initialize():void{
        }
        public function cleanUp():void{
        }
        public function onGameLoaded(_arg1:Object):void{
            this.updateAllRoadTiles();
            this.regenerateRoads();
            this.regenerateNeighborhoods();
        }
        public function onResourceChange(_arg1:MapResource, _arg2:Vector3, _arg3:Vector3):void{
        }
        protected function dbgVerifyConnectivity():void{
            var _local3:MapResource;
            var _local1:Array = Global.world.getObjects();
            var _local2:int;
            for each (_local3 in _local1) {
                if (_local3 == null){
                } else {
                    if (!_local3.isRoadVerifiable){
                    } else {
                        if (_local3.isAdjacentToAnyRoad == _local3.svrIsAdjacentToAnyRoad){
                            _local2++;
                        } else {
                            if (_local3.isAdjacentToAnyRoad){
                            };
                        };
                    };
                };
            };
        }
        public function getRoadSize():Vector3{
            if (this.m_roadSize){
                return (this.m_roadSize.clone());
            };
            return (null);
        }
        public function getSidewalkSize():Vector3{
            if (this.m_sidewalkSize){
                return (this.m_sidewalkSize.clone());
            };
            return (null);
        }
        public function getPathSize(_arg1:RoadDef):Vector3{
            if (_arg1.isSidewalk){
                return (this.getSidewalkSize());
            };
            return (this.getRoadSize());
        }
        public function updateRoads(_arg1:MapResource):void{
            if ((((_arg1 is Road)) || ((_arg1 is Sidewalk)))){
                this.regenerateRoads();
            };
            this.regenerateNeighborhoods();
            if (this.isShowingOverlay){
                this.showOverlay(false);
                this.showOverlay(true);
            };
        }
        public function updateRoadTiles(_arg1:Array):void{
            var _local2:Road;
            for each (_local2 in _arg1) {
                _local2.clearAdjacent();
            };
            for each (_local2 in _arg1) {
                _local2.calculateRoadConnectivity1();
            };
            for each (_local2 in _arg1) {
                _local2.calculateRoadConnectivity2();
            };
            for each (_local2 in _arg1) {
                _local2.calculateRoadConnectivity3();
            };
            for each (_local2 in _arg1) {
                _local2.calculateRoadImage();
                _local2.setState(_local2.getState());
            };
        }
        public function updateAllRoadTiles():void{
            Global.world.citySim.trainManager.generateCrossings();
            var _local1:Array = Global.world.getObjectsByClass(Road);
            this.updateRoadTiles(_local1);
        }
        public function findRandomRoad():Road{
            var _local3:RoadDef;
            var _local4:RoadDef;
            var _local1:RoadGraph = this.findRandomRoadGraph();
            if (_local1 == null){
                return (null);
            };
            var _local2:Array = [];
            for each (_local3 in _local1.defs) {
                if (_local3.road != null){
                    _local2.push(_local3);
                };
            };
            _local4 = MathUtil.randomElement(_local2);
            return (((_local4)!=null) ? _local4.road : null);
        }
        public function findRandomRoadNearEdges(_arg1:Road=null):Road{
            var _local7:RoadDef;
            var _local8:int;
            var _local9:RoadGraph;
            var _local10:RoadDef;
            var _local11:Number;
            var _local2:Rectangle = Global.world.getWorldRect();
            var _local3:Vector3 = new Vector3(((_local2.width / 2) + _local2.left), ((_local2.height / 2) + _local2.top));
            var _local4:Array;
            var _local5:RoadDef;
            if (_arg1){
                if ((((((((_arg1.getPosition().x < this.m_x)) || ((_arg1.getPosition().y < this.m_y)))) || ((_arg1.getPosition().x >= (this.m_x + this.m_width))))) || ((_arg1.getPosition().y >= (this.m_y + this.m_height))))){
                    return (null);
                };
                _local5 = this.m_roads[_arg1.getPosition().x][_arg1.getPosition().y];
                _local4 = _local5.graph.defs;
            } else {
                _local4 = new Array();
                for each (_local9 in this.m_graphs) {
                    for each (_local10 in _local9.defs) {
                        if (((_local10.road) && (!(_local10.road.isBeingMoved())))){
                            _local4.push(_local10);
                        };
                    };
                };
            };
            if (((!(_local4)) || ((_local4.length <= 0)))){
                return (null);
            };
            var _local6:Array = new Array();
            for each (_local7 in _local4) {
                _local11 = 0;
                if (_local7.road != null){
                    _local11 = this.getWeight(_local7, _local5, _local3);
                    if ((((_local7.graph.size < this.MIN_RANDOM_ROAD_GRAPH_LEN)) || ((_local7 == _local5)))){
                        _local11 = 0;
                    };
                };
                _local6.push(_local11);
            };
            _local8 = MathUtil.randomIndexWeighed(_local6);
            if ((((_local8 < 0)) || ((_local8 >= _local4.length)))){
                return (null);
            };
            return (_local4[_local8].road);
        }
        public function findRandomWalkableTile(_arg1:MapResource=null):MapResource{
            var _local5:RoadGraph;
            var _local6:RoadDef;
            var _local2:Array;
            var _local3:RoadDef;
            if (_arg1){
                if ((((((((_arg1.getPosition().x < this.m_x)) || ((_arg1.getPosition().y < this.m_y)))) || ((_arg1.getPosition().x >= (this.m_x + this.m_width))))) || ((_arg1.getPosition().y >= (this.m_y + this.m_height))))){
                    return (_arg1);
                };
                _local3 = this.m_roads[_arg1.getPosition().x][_arg1.getPosition().y];
                _local2 = _local3.graph.defs;
            } else {
                _local2 = new Array();
                for each (_local5 in this.m_graphs) {
                    for each (_local6 in _local5.defs) {
                        if (((_local6.tile) && (!(_local6.tile.isBeingMoved())))){
                            _local2.push(_local6);
                        };
                    };
                };
            };
            if (((!(_local2)) || ((_local2.length <= 0)))){
                return (_arg1);
            };
            var _local4:RoadDef = MathUtil.randomElement(_local2);
            return (((_local4)!=null) ? _local4.tile : _arg1);
        }
        public function findRandomWalkableTileNearEdges(_arg1:MapResource=null):MapResource{
            var _local6:Vector3;
            var _local8:RoadDef;
            var _local9:int;
            var _local10:RoadGraph;
            var _local11:RoadDef;
            var _local12:Number;
            var _local2:Rectangle = Global.world.getWorldRect();
            var _local3:Vector3 = new Vector3(((_local2.width / 2) + _local2.left), ((_local2.height / 2) + _local2.top));
            var _local4:Array;
            var _local5:RoadDef;
            if (((_arg1) && ((((_arg1 is Road)) || ((_arg1 is Sidewalk)))))){
                _local6 = _arg1.getPosition().clone();
                if ((((((((_local6.x < this.m_x)) || ((_local6.y < this.m_y)))) || ((_local6.x >= (this.m_x + this.m_width))))) || ((_local6.y >= (this.m_y + this.m_height))))){
                    return (null);
                };
                _local5 = this.m_roads[_local6.x][_local6.y];
                _local4 = _local5.graph.defs;
            } else {
                _local4 = new Array();
                for each (_local10 in this.m_graphs) {
                    for each (_local11 in _local10.defs) {
                        if (((_local11.tile) && (!(_local11.tile.isBeingMoved())))){
                            _local4.push(_local11);
                        };
                    };
                };
            };
            if (((!(_local4)) || ((_local4.length <= 0)))){
                return (null);
            };
            var _local7:Array = new Array();
            for each (_local8 in _local4) {
                _local12 = 0;
                if (_local8.tile){
                    _local12 = this.getWeight(_local8, _local5, _local3);
                    if ((((_local8.graph.size < this.MIN_RANDOM_ROAD_GRAPH_LEN)) || ((_local8 == _local5)))){
                        _local12 = 0;
                    };
                };
                _local7.push(_local12);
            };
            _local9 = MathUtil.randomIndexWeighed(_local7);
            if ((((_local9 < 0)) || ((_local9 >= _local4.length)))){
                return (null);
            };
            return (_local4[_local9].tile);
        }
        protected function getWeight(_arg1:RoadDef, _arg2:RoadDef, _arg3:Vector3):Number{
            var _local8:*;
            var _local9:Vector3;
            var _local4:Vector3 = _arg1.tile.getPosition().subtract(_arg3);
            var _local5:Number = _arg1.tile.getPosition().subtract(_arg3).dot(_local4);
            if (_arg2){
                _local9 = _arg1.tile.getPosition().subtract(_arg2.tile.getPosition());
                _local5 = (_local5 + _local9.dot(_local9));
            };
            var _local6:int;
            var _local7:Array = _arg1.roads;
            for each (_local8 in _local7) {
                if (_local8){
                    _local6++;
                };
            };
            _local5 = (_local5 + Math.pow(this.m_endpointInfluence, (4 - _local6)));
            return (_local5);
        }
        public function findClosestRoad(_arg1:Vector3):Road{
            var _local2:RoadDef = this.findClosestRoadDef(_arg1, true);
            return (((_local2)!=null) ? _local2.road : null);
        }
        public function findClosestWalkableTile(_arg1:Vector3, _arg2:Function=null):MapResource{
            var _local3:RoadDef = this.findClosestRoadDef(_arg1, false, _arg2);
            return ((_local3.road) ? _local3.road : _local3.sidewalk);
        }
        public function findClosestWalkableTileInGraph(_arg1:Vector3, _arg2:RoadGraph):MapResource{
            var _local5:RoadDef;
            var _local6:Number;
            var _local7:Number;
            var _local8:Vector3;
            var _local9:Number;
            var _local3:RoadDef;
            var _local4:Number = Number.POSITIVE_INFINITY;
            for each (_local5 in _arg2.defs) {
                _local6 = (_local5.isSidewalk) ? (SIDEWALK_WIDTH / 2) : (this.m_roadSize.x / 2);
                _local7 = (_local5.isSidewalk) ? (SIDEWALK_HEIGHT / 2) : (this.m_roadSize.y / 2);
                _local8 = new Vector3((_local5.x + _local6), (_local5.y + _local7));
                _local9 = _arg1.subtract(_local8).length();
                if (_local9 < _local4){
                    _local3 = _local5;
                    _local4 = _local9;
                };
            };
            return ((_local3) ? (_local3.road) ? _local3.road : _local3.sidewalk : null);
        }
        public function findAllGraphsForWalkableTile(_arg1:MapResource):Array{
            var _local3:RoadGraph;
            var _local4:RoadDef;
            var _local2:Array = [];
            for each (_local3 in this.m_graphs) {
                for each (_local4 in _local3.defs) {
                    if ((((_local4.road == _arg1)) || ((_local4.sidewalk == _arg1)))){
                        _local2.push(_local3);
                        break;
                    };
                };
            };
            return (_local2);
        }
        public function findClosestRoadNeighbors(_arg1:Vector3):Array{
            var _local2:RoadDef = this.findClosestRoadDef(_arg1, true);
            if (_local2 == null){
                return (null);
            };
            return (_local2.roads.map(RoadDef.extractRoad));
        }
        function findClosestRoadDef(_arg1:Vector3, _arg2:Boolean, _arg3:Function=null):RoadDef{
            var _local6:RoadGraph;
            var _local7:RoadDef;
            var _local8:Number;
            var _local9:Number;
            var _local10:Vector3;
            var _local11:Number;
            var _local4:RoadDef;
            var _local5:Number = Number.POSITIVE_INFINITY;
            for each (_local6 in this.m_graphs) {
                for each (_local7 in _local6.defs) {
                    if (((_arg2) && ((_local7.road == null)))){
                    } else {
                        if (_arg3 != null){
                            //unresolved if
                        } else {
                            _local8 = (_local7.isSidewalk) ? (SIDEWALK_WIDTH / 2) : (this.m_roadSize.x / 2);
                            _local9 = (_local7.isSidewalk) ? (SIDEWALK_HEIGHT / 2) : (this.m_roadSize.y / 2);
                            _local10 = new Vector3((_local7.x + _local8), (_local7.y + _local9));
                            _local11 = _arg1.subtract(_local10).length();
                            if (_local11 < _local5){
                                _local4 = _local7;
                                _local5 = _local11;
                            };
                        };
                    };
                };
            };
            return (_local4);
        }
        public function hasWalkableRoad():Boolean{
            var _local3:RoadGraph;
            if (this.m_graphs.length == 0){
                return (false);
            };
            var _local1:Array = [];
            var _local2:Array = [];
            for each (_local3 in this.m_graphs) {
                if (!_local3.hasRoads){
                } else {
                    if (_local3.size > 1){
                        return (true);
                    };
                };
            };
            return (false);
        }
        protected function findRandomRoadGraph():RoadGraph{
            var _local3:RoadGraph;
            var _local4:int;
            if (this.m_graphs.length == 0){
                return (null);
            };
            var _local1:Array = [];
            var _local2:Array = [];
            for each (_local3 in this.m_graphs) {
                if (!_local3.hasRoads){
                } else {
                    _local1.push(_local3);
                    _local2.push(_local3.size);
                };
            };
            _local4 = MathUtil.randomIndexWeighed(_local2);
            return ((_local1[_local4] as RoadGraph));
        }
        public function getConnectedRoadGraph(_arg1:MapResource):RoadGraph{
            var _local2:RoadGraph;
            for each (_local2 in this.m_graphs) {
                if (_local2.hasClosestRoad(_arg1)){
                    return (_local2);
                };
            };
            return (null);
        }
        public function findPath(_arg1:MapResource, _arg2:MapResource, _arg3:int):Object{
            var _local8:RoadDef;
            var _local11:RoadDef;
            var _local12:Boolean;
            var _local13:RoadDef;
            var _local14:Number;
            var _local15:Number;
            var _local16:int;
            var _local17:PathElement;
            var _local18:Array;
            var _local19:Vector3;
            var _local20:PathElement;
            var _local21:Vector3;
            var _local4:Array = this.findNearestRoads(_arg1);
            var _local5:Array = this.findNearestRoads(_arg2);
            if ((((_local4.length == 0)) || ((_local5.length == 0)))){
                return (null);
            };
            var _local6:RoadDef;
            var _local7:RoadDef;
            for each (_local8 in _local4) {
                for each (_local13 in _local5) {
                    if (_local8.graph == _local13.graph){
                        _local6 = _local8;
                        _local7 = _local13;
                        break;
                    };
                };
            };
            if ((((((_local6 == null)) || ((_local7 == null)))) || (!((_local6.graph == _local7.graph))))){
                return (null);
            };
            if (!_local6.graph){
                return (null);
            };
            var _local9:Array = _local6.graph.findPath(_local6, _local7);
            if (_local9 == null){
                return (null);
            };
            var _local10:Array = [new PathElement(_arg1.getHotspot(), null, PathElement.TYPE_NONROAD)];
            for each (_local11 in _local9) {
                if (_local11 == null){
                } else {
                    if ((((_arg3 == PATH_ROAD_ONLY)) && (_local11.isSidewalk))){
                        break;
                    };
                    _local14 = (_local11.isSidewalk) ? (SIDEWALK_WIDTH / 2) : (this.m_roadSize.x / 2);
                    _local15 = (_local11.isSidewalk) ? (SIDEWALK_HEIGHT / 2) : (this.m_roadSize.y / 2);
                    _local16 = (_local11.isSidewalk) ? PathElement.TYPE_NONROAD : PathElement.TYPE_ROAD;
                    _local10.push(new PathElement(new Vector3((_local11.x + _local14), (_local11.y + _local15)), null, _local16));
                };
            };
            _local12 = (_arg2 is HarvestableResource);
            if (((!((_arg3 == PATH_ROAD_ONLY))) && (_local12))){
                _local17 = _local10[(_local10.length - 1)];
                _local18 = this.findPathFromRoadToEntrance(_local17.basePosition, _arg2);
                for each (_local19 in _local18) {
                    _local10.push(new PathElement(_local19, null, PathElement.TYPE_NONROAD));
                };
            };
            _local12 = (_arg1 is HarvestableResource);
            if (((((!((_arg3 == PATH_ROAD_ONLY))) && (_local12))) && ((_local10.length > 1)))){
                _local20 = _local10[1];
                _local18 = this.findPathFromRoadToEntrance(_local20.basePosition, _arg1);
                if (_local18.length > 0){
                    _local10.splice(0, 1);
                    for each (_local19 in _local18) {
                        _local10.splice(0, 0, new PathElement(_local19, null, PathElement.TYPE_NONROAD));
                    };
                };
            };
            switch (_arg3){
                case PATH_TO_FRONT_ENTRANCE:
                    _local10.push(new PathElement(_arg2.getHotspot(), null, PathElement.TYPE_NONROAD));
                    break;
                case PATH_FULL:
                    for each (_local21 in _arg2.getHotspots()) {
                        _local10.push(new PathElement(_local21, null, PathElement.TYPE_NONROAD));
                    };
                    break;
            };
            return ({
                path:_local10,
                graph:_local6.graph
            });
        }
        public function createInvisiblePeepPath(_arg1:MapResource, _arg2:MapResource):Object{
            if ((((_arg1 == null)) || ((_arg2 == null)))){
                return (null);
            };
            var _local3:Vector3 = _arg1.getHotspot();
            var _local4:Vector3 = _arg2.getHotspot();
            if ((((_local3 == null)) || ((_local4 == null)))){
                return (null);
            };
            var _local5:Vector3 = new Vector3(_local3.x, _local4.y, _local4.z);
            var _local6:Array = [new PathElement(_local3, null, PathElement.TYPE_NONROAD), new PathElement(_local5, null, PathElement.TYPE_NONROAD), new PathElement(_local4, null, PathElement.TYPE_NONROAD)];
            return ({
                path:_local6,
                graph:null
            });
        }
        protected function findPathFromRoadToEntrance(_arg1:Vector3, _arg2:MapResource):Array{
            var _local6:Vector3;
            var _local7:Array;
            var _local8:Vector3;
            var _local9:Number;
            var _local10:Number;
            var _local3:Vector3 = _arg2.getPosition();
            var _local4:Vector3 = _arg2.getSize();
            var _local5:Array = [new Vector3(0, 0), new Vector3(1, 0), new Vector3(1, 1), new Vector3(0, 1)];
            for each (_local6 in _local5) {
                _local6.x = (_local3.x + (_local6.x * _local4.x));
                _local6.y = (_local3.y + (_local6.y * _local4.y));
            };
            _local7 = [];
            _local8 = _arg2.getHotspot();
            _local9 = (_local8.x - (_local3.x + (_local4.x * 0.5)));
            _local10 = (_local8.y - (_local3.y + (_local4.y * 0.5)));
            if (Math.abs(_local9) > Math.abs(_local10)){
                if (_local9 > 0){
                    if (_arg1.x > (_local3.x + _local4.x)){
                        return (_local7);
                    };
                } else {
                    if (_arg1.x < _local3.x){
                        return (_local7);
                    };
                };
            } else {
                if (_local10 > 0){
                    if (_arg1.y > (_local3.y + _local4.y)){
                        return (_local7);
                    };
                } else {
                    if (_arg1.y < _local3.y){
                        return (_local7);
                    };
                };
            };
            var _local11:Vector3 = this.findClosestWaypoint(_local8, _arg1, _local5);
            if (_local11 == null){
                return ([]);
            };
            ArrayUtil.removeValueFromArray(_local5, _local11);
            var _local12:Vector3 = this.findClosestWaypoint(_local8, _local11, _local5);
            if (_local12 == null){
                return ([_local11]);
            };
            return ([_local11, _local12]);
        }
        protected function findClosestWaypoint(_arg1:Vector3, _arg2:Vector3, _arg3:Array):Vector3{
            var _local7:Vector3;
            var _local8:Number;
            var _local9:Number;
            var _local10:Number;
            var _local4:Vector3;
            var _local5:Number = int.MAX_VALUE;
            var _local6:Number = _arg1.subtract(_arg2).length();
            for each (_local7 in _arg3) {
                _local8 = _local7.subtract(_arg2).length();
                _local9 = _local7.subtract(_arg1).length();
                _local10 = (_local8 + _local9);
                if ((((_local8 < _local6)) && ((((_local4 == null)) || ((_local10 <= _local5)))))){
                    _local4 = _local7;
                    _local5 = _local10;
                };
            };
            return (_local4);
        }
        protected function findNearestRoads(_arg1:MapResource):Array{
            var _local3:RoadGraph;
            var _local4:Vector3;
            var _local5:RoadDef;
            var _local6:RoadDef;
            if ((((_arg1 is Road)) || ((_arg1 is Sidewalk)))){
                _local4 = _arg1.getPosition();
                _local5 = (this.m_roads[_local4.x][_local4.y] as RoadDef);
                if (_local5 != null){
                    return ([_local5]);
                };
            };
            var _local2:Array = [];
            for each (_local3 in this.m_graphs) {
                _local6 = _local3.getClosestRoad(_arg1);
                if (_local6 != null){
                    _local2.push(_local6);
                };
            };
            return (_local2);
        }
        protected function regenerateRoads():void{
            var _local1:Rectangle = this.m_world.getWorldRect();
            this.m_x = _local1.x;
            this.m_y = _local1.y;
            this.m_width = _local1.width;
            this.m_height = _local1.height;
            this.clearRoadMatrix();
            this.fillRoadMatrix();
            this.makeGraphs();
        }
        protected function regenerateNeighborhoods():void{
            this.clearBuildings();
            this.updateBuildings();
        }
        protected function fillRoadMatrix():void{
            var _local2:Road;
            var _local3:int;
            var _local5:Sidewalk;
            var _local6:Vector3;
            var _local7:int;
            var _local8:Road;
            var _local9:Vector3;
            var _local10:Number;
            var _local11:int;
            var _local1:Array = this.m_world.getObjectsByClass(Road);
            for each (_local2 in _local1) {
                _local6 = _local2.getPosition();
                if (((!(this.m_roads[_local6.x])) && (!(this.m_isStatSent)))){
                    StatsManager.count("user_stuck", "outside_expansion", "road");
                    StatsManager.sendStats(true);
                    this.m_isStatSent = true;
                };
                this.m_roads[_local6.x][_local6.y] = new RoadDef(_local2, _local6.x, _local6.y, false);
                if (_local2.adjacentRoads == null){
                } else {
                    _local7 = 0;
                    while (_local7 < _local2.adjacentRoads.length) {
                        _local8 = _local2.adjacentRoads[_local7];
                        if (((!((_local8 == null))) && (_local2.shouldAdjust(_local8, _local7)))){
                            _local9 = _local8.getPosition();
                            _local10 = Math.abs((_local9.x - _local6.x));
                            if ((((_local10 > 0.9)) && ((_local10 < 1.1)))){
                                if (this.m_roads[_local9.x][_local6.y] == null){
                                    this.m_roads[_local9.x][_local6.y] = new RoadDef(_local2, _local9.x, _local6.y, false);
                                };
                            };
                            _local10 = Math.abs((_local6.y - _local9.y));
                            if ((((_local10 > 0.9)) && ((_local10 < 1.1)))){
                                if (this.m_roads[_local6.x][_local9.y] == null){
                                    this.m_roads[_local6.x][_local9.y] = new RoadDef(_local2, _local6.x, _local9.y, false);
                                };
                            };
                        };
                        _local7++;
                    };
                };
            };
            this.m_roadSize = new Vector3(ROAD_WIDTH, ROAD_HEIGHT);
            this.m_sidewalkSize = new Vector3(SIDEWALK_WIDTH, SIDEWALK_HEIGHT);
            _local3 = this.m_x;
            while (_local3 < (this.m_x + this.m_width)) {
                _local11 = this.m_y;
                while (_local11 < (this.m_y + this.m_height)) {
                    this.updateRoad(_local3, _local11);
                    _local11++;
                };
                _local3++;
            };
            var _local4:Array = this.m_world.getObjectsByClass(Sidewalk);
            for each (_local5 in _local4) {
                _local6 = _local5.getPosition();
                if (((!(this.m_roads[_local6.x])) && (!(this.m_isStatSent)))){
                    StatsManager.count("user_stuck", "outside_expansion", "sidewalk");
                    StatsManager.sendStats(true);
                    this.m_isStatSent = true;
                };
                this.m_roads[_local6.x][_local6.y] = new RoadDef(null, _local6.x, _local6.y, true, _local5);
            };
            _local3 = this.m_x;
            while (_local3 < (this.m_x + this.m_width)) {
                _local11 = this.m_y;
                while (_local11 < (this.m_y + this.m_height)) {
                    this.updateSidewalk(_local3, _local11);
                    _local11++;
                };
                _local3++;
            };
            _local3 = this.m_x;
            while (_local3 < (this.m_x + this.m_width)) {
                _local11 = this.m_y;
                while (_local11 < (this.m_y + this.m_height)) {
                    this.updateRoadToSidewalks(_local3, _local11);
                    _local11++;
                };
                _local3++;
            };
        }
        protected function clearRoadMatrix():void{
            var _local2:Array;
            var _local3:int;
            this.m_roads = new Array(this.m_width);
            var _local1:int = this.m_x;
            while (_local1 < (this.m_x + this.m_width)) {
                _local2 = new Array(this.m_height);
                _local3 = this.m_y;
                while (_local3 < (this.m_y + this.m_height)) {
                    _local2[_local3] = null;
                    _local3++;
                };
                this.m_roads[_local1] = _local2;
                _local1++;
            };
        }
        protected function processNeighbor(_arg1:RoadDef, _arg2:RoadDef):Boolean{
            var _local3:Boolean;
            var _local4:Road;
            if (_arg2 != null){
                _local3 = (_arg1.road == _arg2.road);
                for each (_local4 in _arg1.road.adjacentRoads) {
                    if (_local4 == _arg2.road){
                        _local3 = true;
                    };
                };
                if (_local3){
                    _arg1.roads.push(_arg2);
                };
                return (true);
            };
            return (false);
        }
        protected function updateSidewalk(_arg1:int, _arg2:int):void{
            var _local5:Array;
            var _local6:int;
            var _local7:int;
            var _local8:RoadDef;
            var _local3:RoadDef = (this.m_roads[_arg1][_arg2] as RoadDef);
            if (_local3 == null){
                return;
            };
            if (!_local3.isSidewalk){
                return;
            };
            var _local4:Array = [[-1, 0], [0, -1], [1, 0], [0, 1]];
            for each (_local5 in _local4) {
                _local6 = (_arg1 + _local5[0]);
                _local7 = (_arg2 + _local5[1]);
                if ((((((((_local6 < this.m_x)) || ((_local6 >= (this.m_x + this.m_width))))) || ((_local7 < this.m_y)))) || ((_local7 >= (this.m_y + this.m_height))))){
                } else {
                    _local8 = (this.m_roads[_local6][_local7] as RoadDef);
                    if (((!((_local8 == null))) && (_local8.isSidewalk))){
                        _local3.roads.push(_local8);
                    };
                };
            };
        }
        protected function updateRoad(_arg1:int, _arg2:int):void{
            var _local5:int;
            var _local6:int;
            var _local3:RoadDef = (this.m_roads[_arg1][_arg2] as RoadDef);
            if (_local3 == null){
                return;
            };
            var _local4 = 1;
            while (_local4 <= (this.m_roadSize.x + 1)) {
                _local5 = (_arg1 + _local4);
                _local6 = _arg2;
                if ((((((((_local5 < this.m_x)) || ((_local5 >= (this.m_x + this.m_width))))) || ((_local6 < this.m_y)))) || ((_local6 >= (this.m_y + this.m_height))))){
                } else {
                    if (this.processNeighbor(_local3, (this.m_roads[_local5][_local6] as RoadDef))){
                        break;
                    };
                };
                _local4++;
            };
            _local4 = 1;
            while (_local4 <= (this.m_roadSize.x + 1)) {
                _local5 = (_arg1 - _local4);
                _local6 = _arg2;
                if ((((((((_local5 < this.m_x)) || ((_local5 >= (this.m_x + this.m_width))))) || ((_local6 < this.m_y)))) || ((_local6 >= (this.m_y + this.m_height))))){
                } else {
                    if (this.processNeighbor(_local3, (this.m_roads[_local5][_local6] as RoadDef))){
                        break;
                    };
                };
                _local4++;
            };
            _local4 = 1;
            while (_local4 <= (this.m_roadSize.y + 1)) {
                _local5 = _arg1;
                _local6 = (_arg2 + _local4);
                if ((((((((_local5 < this.m_x)) || ((_local5 >= (this.m_x + this.m_width))))) || ((_local6 < this.m_y)))) || ((_local6 >= (this.m_y + this.m_height))))){
                } else {
                    if (this.processNeighbor(_local3, (this.m_roads[_local5][_local6] as RoadDef))){
                        break;
                    };
                };
                _local4++;
            };
            _local4 = 1;
            while (_local4 <= (this.m_roadSize.y + 1)) {
                _local5 = _arg1;
                _local6 = (_arg2 - _local4);
                if ((((((((_local5 < this.m_x)) || ((_local5 >= (this.m_x + this.m_width))))) || ((_local6 < this.m_y)))) || ((_local6 >= (this.m_y + this.m_height))))){
                } else {
                    if (this.processNeighbor(_local3, (this.m_roads[_local5][_local6] as RoadDef))){
                        break;
                    };
                };
                _local4++;
            };
        }
        protected function updateRoadToSidewalks(_arg1:int, _arg2:int):void{
            var _local15:int;
            var _local16:RoadDef;
            var _local17:Number;
            var _local3:RoadDef = (this.m_roads[_arg1][_arg2] as RoadDef);
            if ((((_local3 == null)) || (_local3.isSidewalk))){
                return;
            };
            var _local4:Number = (this.m_roadSize.x / 2);
            var _local5:Number = (this.m_roadSize.y / 2);
            var _local6:Number = 0.5;
            var _local7:Number = 0.5;
            var _local8:Vector3 = _local3.road.getSize();
            var _local9:Vector3 = _local3.road.getPosition();
            var _local10:Vector3 = new Vector3((_local3.x + _local4), (_local3.y + _local5));
            var _local11:Number = 99999;
            var _local12:RoadDef;
            var _local13:Vector3 = new Vector3();
            var _local14:int = _local9.x;
            while (_local14 < (_local9.x + _local8.x)) {
                _local15 = (_local9.y + _local8.y);
                if ((((((((_local14 < this.m_x)) || ((_local14 >= (this.m_x + this.m_width))))) || ((_local15 < this.m_y)))) || ((_local15 >= (this.m_y + this.m_height))))){
                } else {
                    _local16 = (this.m_roads[_local14][_local15] as RoadDef);
                    if ((((_local16 == null)) || (!(_local16.isSidewalk)))){
                    } else {
                        _local13.x = ((_local16.x + _local6) - _local10.x);
                        _local13.y = ((_local16.y + _local7) - _local10.y);
                        _local17 = _local13.length();
                        if ((((_local12 == null)) || ((_local17 < _local11)))){
                            _local12 = _local16;
                            _local11 = _local17;
                        };
                    };
                };
                _local14++;
            };
            if (_local12 != null){
                _local3.roads.push(_local12);
                _local12.roads.push(_local3);
            };
            _local11 = 99999;
            _local12 = null;
            _local14 = _local9.x;
            while (_local14 < (_local9.x + _local8.x)) {
                _local15 = (_local9.y - 1);
                if ((((((((_local14 < this.m_x)) || ((_local14 >= (this.m_x + this.m_width))))) || ((_local15 < this.m_y)))) || ((_local15 >= (this.m_y + this.m_height))))){
                } else {
                    _local16 = (this.m_roads[_local14][_local15] as RoadDef);
                    if ((((_local16 == null)) || (!(_local16.isSidewalk)))){
                    } else {
                        _local13.x = ((_local16.x + _local6) - _local10.x);
                        _local13.y = ((_local16.y + _local7) - _local10.y);
                        _local17 = _local13.length();
                        if ((((_local12 == null)) || ((_local17 < _local11)))){
                            _local12 = _local16;
                            _local11 = _local17;
                        };
                    };
                };
                _local14++;
            };
            if (_local12 != null){
                _local3.roads.push(_local12);
                _local12.roads.push(_local3);
                _local11 = 99999;
                _local12 = null;
            };
            _local15 = _local9.y;
            while (_local15 < (_local9.y + _local8.y)) {
                _local14 = (_local9.x - 1);
                if ((((((((_local14 < this.m_x)) || ((_local14 >= (this.m_x + this.m_width))))) || ((_local15 < this.m_y)))) || ((_local15 >= (this.m_y + this.m_height))))){
                } else {
                    _local16 = (this.m_roads[_local14][_local15] as RoadDef);
                    if ((((_local16 == null)) || (!(_local16.isSidewalk)))){
                    } else {
                        _local13.x = ((_local16.x + _local6) - _local10.x);
                        _local13.y = ((_local16.y + _local7) - _local10.y);
                        _local17 = _local13.length();
                        if ((((_local12 == null)) || ((_local17 < _local11)))){
                            _local12 = _local16;
                            _local11 = _local17;
                        };
                    };
                };
                _local15++;
            };
            if (_local12 != null){
                _local3.roads.push(_local12);
                _local12.roads.push(_local3);
                _local11 = 99999;
                _local12 = null;
            };
            _local15 = _local9.y;
            while (_local15 < (_local9.y + _local8.y)) {
                _local14 = (_local9.x + _local8.x);
                if ((((((((_local14 < this.m_x)) || ((_local14 >= (this.m_x + this.m_width))))) || ((_local15 < this.m_y)))) || ((_local15 >= (this.m_y + this.m_height))))){
                } else {
                    _local16 = (this.m_roads[_local14][_local15] as RoadDef);
                    if ((((_local16 == null)) || (!(_local16.isSidewalk)))){
                    } else {
                        _local13.x = ((_local16.x + _local6) - _local10.x);
                        _local13.y = ((_local16.y + _local7) - _local10.y);
                        _local17 = _local13.length();
                        if ((((_local12 == null)) || ((_local17 < _local11)))){
                            _local12 = _local16;
                            _local11 = _local17;
                        };
                    };
                };
                _local15++;
            };
            if (_local12 != null){
                _local3.roads.push(_local12);
                _local12.roads.push(_local3);
            };
        }
        protected function makeGraphs():void{
            var _local2:int;
            var _local3:RoadDef;
            var _local4:Array;
            var _local5:RoadGraph;
            var _local6:RoadDef;
            this.m_graphs = [];
            RoadGraph.nextColorIndex = 0;
            var _local1:int = this.m_x;
            while (_local1 < (this.m_x + this.m_width)) {
                _local2 = this.m_y;
                while (_local2 < (this.m_y + this.m_height)) {
                    _local3 = this.m_roads[_local1][_local2];
                    if (((!((_local3 == null))) && ((_local3.graph == null)))){
                        _local4 = this.getAllRoads(_local3);
                        _local5 = new RoadGraph();
                        for each (_local6 in _local4) {
                            _local5.add(_local6);
                        };
                        this.m_graphs.push(_local5);
                    };
                    _local2++;
                };
                _local1++;
            };
        }
        protected function getAllRoads(_arg1:RoadDef):Array{
            var _local4:RoadDef;
            var _local5:RoadDef;
            var _local2:Dictionary = new Dictionary();
            var _local3:Array = [_arg1];
            while (_local3.length > 0) {
                _local4 = (_local3.shift() as RoadDef);
                if ((((_local4.graph == null)) && ((_local2[_local4] == null)))){
                    _local2[_local4] = true;
                    for each (_local5 in _local4.roads) {
                        _local3.push(_local5);
                    };
                };
            };
            return (DictionaryUtil.getKeys(_local2));
        }
        protected function clearBuildings():void{
            var _local1:RoadGraph;
            var _local2:RoadDef;
            for each (_local1 in this.m_graphs) {
                _local1.closestRoad = new Dictionary();
                for each (_local2 in _local1.defs) {
                    _local2.buildings = [];
                };
            };
        }
        protected function updateBuildings():void{
            var _local5:MapResource;
            var _local6:RoadGraph;
            var _local7:RoadDef;
            var _local8:Box3D;
            var _local9:Array;
            var _local10:WorldObject;
            var _local1:CollisionMap = Global.world.getCollisionMap();
            var _local2 = 1;
            var _local3:Vector3 = new Vector3((this.m_roadSize.x + (_local2 * 2)), (this.m_roadSize.y + (_local2 * 2)));
            var _local4:Array = Global.world.getObjectsByClass(MapResource);
            for each (_local5 in _local4) {
                _local5.clearRoadSideFlags();
            };
            for each (_local6 in this.m_graphs) {
                for each (_local7 in _local6.defs) {
                    _local8 = new Box3D(new Vector3((_local7.x - 1), (_local7.y - 1)), _local3);
                    _local9 = _local1.getIntersectingObjects(_local8);
                    for each (_local10 in _local9) {
                        this.maybeAddResource(_local10, _local7, _local6);
                    };
                };
            };
            for each (_local5 in _local4) {
                _local5.updateRoadState();
            };
        }
        public function updateResource(_arg1:MapResource):void{
            var _local2:RoadGraph;
            var _local3:RoadDef;
            _arg1.clearRoadSideFlags();
            for each (_local2 in this.m_graphs) {
                for each (_local3 in _local2.defs) {
                    this.maybeAddResource(_arg1, _local3, _local2);
                };
            };
            _arg1.updateRoadState();
        }
        protected function maybeAddResource(_arg1:WorldObject, _arg2:RoadDef, _arg3:RoadGraph):void{
            var _local4:MapResource = (_arg1 as MapResource);
            if ((((((((((_local4 == null)) || ((_local4 is Road)))) || ((_local4 is Sidewalk)))) || ((_local4 is Wilderness)))) || ((_local4 is TrainTracks)))){
                return;
            };
            var _local5:Vector3 = _local4.getHotspot();
            var _local6:Number = this.getPathSize(_arg2).x;
            var _local7:Number = this.getPathSize(_arg2).y;
            var _local8:Box3D = _arg1.getBoundingBox();
            var _local9:Number = (Math.min((_local8.x + _local8.width), (_arg2.x + _local6)) - Math.max(_local8.x, _arg2.x));
            var _local10:Number = (Math.min((_local8.y + _local8.height), (_arg2.y + _local7)) - Math.max(_local8.y, _arg2.y));
            var _local11:Boolean = (((((_local9 == 0)) && ((_local10 > 0)))) || ((((_local10 == 0)) && ((_local9 > 0)))));
            if (!_local11){
                return;
            };
            if (_local9 == 0){
                if ((_local8.x + _local8.width) == _arg2.x){
                    _local4.setRoadSideFlag(_local4.RIGHT_SIDE);
                } else {
                    if (_local8.x == (_arg2.x + _local6)){
                        _local4.setRoadSideFlag(_local4.LEFT_SIDE);
                    };
                };
            } else {
                if (_local10 == 0){
                    if ((_local8.y + _local8.height) == _arg2.y){
                        _local4.setRoadSideFlag(_local4.TOP_SIDE);
                    } else {
                        if (_local8.y == (_arg2.y + _local7)){
                            _local4.setRoadSideFlag(_local4.BOTTOM_SIDE);
                        };
                    };
                };
            };
            if (_arg3.hasRoads){
                _local4.setConnectsRoadFlag(true);
            };
            var _local12:RoadDef = _arg3.getClosestRoad(_local4);
            if (_local12 == null){
                _arg3.setClosestRoad(_local4, _arg2);
                return;
            };
            var _local13:Vector3 = new Vector3((_local12.x + (this.m_roadSize.x / 2)), (_local12.y + (this.m_roadSize.y / 2)));
            var _local14:Number = _local13.subtract(_local5).length();
            var _local15:Vector3 = new Vector3((_arg2.x + (_local6 / 2)), (_arg2.y + (_local7 / 2)));
            var _local16:Number = _local15.subtract(_local5).length();
            if (_local16 < _local14){
                _arg3.setClosestRoad(_local4, _arg2);
            };
        }
        function showOverlay(_arg1:Boolean):void{
            if ((((this.m_roadOverlay == null)) && (_arg1))){
                this.m_roadOverlay = new Sprite();
                this.drawOverlay(this.m_roadOverlay);
                GlobalEngine.viewport.objectBase.addChild(this.m_roadOverlay);
            } else {
                if (((!((this.m_roadOverlay == null))) && (!(_arg1)))){
                    if (this.m_roadOverlay.parent){
                        this.m_roadOverlay.parent.removeChild(this.m_roadOverlay);
                    };
                    this.m_roadOverlay = null;
                };
            };
        }
        public function get isShowingOverlay():Boolean{
            return (!((this.m_roadOverlay == null)));
        }
        public function findRandomRoadOnScreen(_arg1:Road):Road{
            var _local6:RoadDef;
            var _local7:int;
            var _local8:Number;
            var _local2:Vector3 = _arg1.getPosition();
            var _local3:Array;
            var _local4:RoadDef;
            if ((((((((_arg1.getPosition().x < this.m_x)) || ((_arg1.getPosition().y < this.m_y)))) || ((_arg1.getPosition().x >= (this.m_x + this.m_width))))) || ((_arg1.getPosition().y >= (this.m_y + this.m_height))))){
                return (_arg1);
            };
            _local4 = this.m_roads[_arg1.getPosition().x][_arg1.getPosition().y];
            _local3 = _local4.graph.defs;
            if (((!(_local3)) || ((_local3.length <= 0)))){
                return (_arg1);
            };
            var _local5:Array = new Array();
            for each (_local6 in _local3) {
                _local8 = 0;
                if (_local6.road != null){
                    _local8 = this.getOnScreenWeight(_local6, _local4);
                };
                if ((((_local6.graph.size < this.MIN_RANDOM_ROAD_GRAPH_LEN)) || ((_local6 == _local4)))){
                    _local8 = 0;
                };
                _local5.push(_local8);
            };
            _local7 = MathUtil.randomIndexWeighed(_local5);
            if ((((_local7 < 0)) || ((_local7 >= _local3.length)))){
                return (_arg1);
            };
            return (_local3[_local7].road);
        }
        protected function getOnScreenWeight(_arg1:RoadDef, _arg2:RoadDef):Number{
            var _local3 = 20;
            var _local4:Number = 20;
            var _local5:Point = IsoMath.tilePosToPixelPos((_arg1.x + (RoadManager.ROAD_WIDTH / 2)), (_arg1.y + (RoadManager.ROAD_HEIGHT / 2)));
            _local5 = IsoMath.viewportToStage(_local5);
            if ((((((((_local5.x < _local3)) || ((_local5.y < _local3)))) || (((_local5.x + _local3) > GlobalEngine.viewport.stage.stageWidth)))) || (((_local5.y + _local3) > GlobalEngine.viewport.stage.stageHeight)))){
                return (0);
            };
            var _local6:Vector3 = _arg1.road.getPosition().subtract(_arg2.road.getPosition());
            var _local7:Number = _arg1.road.getPosition().subtract(_arg2.road.getPosition()).dot(_local6);
            if (_local7 > (_local4 * _local4)){
                _local7 = ((_local4 * _local4) / ((1 + _local7) - (_local4 * _local4)));
            };
            return (_local7);
        }
        private function drawOverlay(_arg1:Sprite):void{
            var _local8:int;
            var _local9:RoadDef;
            var _local10:Number;
            var _local11:Number;
            var _local12:Point;
            var _local13:RoadDef;
            var _local14:MapResource;
            var _local15:Number;
            var _local16:Number;
            var _local17:Point;
            var _local18:Vector.<Vector3>;
            var _local19:Vector3;
            var _local2:Number = (this.m_roadSize.x / 2);
            var _local3:Number = (this.m_roadSize.y / 2);
            var _local4:Number = (SIDEWALK_WIDTH / 2);
            var _local5:Number = (SIDEWALK_HEIGHT / 2);
            var _local6:Graphics = _arg1.graphics;
            _local6.clear();
            var _local7:int = this.m_x;
            while (_local7 < (this.m_x + this.m_width)) {
                _local8 = this.m_y;
                while (_local8 < (this.m_y + this.m_height)) {
                    _local9 = (this.m_roads[_local7][_local8] as RoadDef);
                    if (_local9 == null){
                    } else {
                        _local10 = (_local9.isSidewalk) ? _local4 : _local2;
                        _local11 = (_local9.isSidewalk) ? _local5 : _local3;
                        _local6.lineStyle(1, _local9.graph.debugColor);
                        _local12 = IsoMath.tilePosToPixelPos((_local9.x + _local10), (_local9.y + _local11));
                        for each (_local13 in _local9.roads) {
                            _local15 = (_local13.isSidewalk) ? _local4 : _local2;
                            _local16 = (_local13.isSidewalk) ? _local5 : _local3;
                            _local17 = IsoMath.tilePosToPixelPos((_local13.x + _local15), (_local13.y + _local16));
                            _local6.moveTo(_local12.x, _local12.y);
                            _local6.lineTo(_local17.x, _local17.y);
                        };
                        _local6.moveTo(_local12.x, _local12.y);
                        _local6.lineTo((_local12.x + 1), _local12.y);
                        _local6.lineStyle(1, _local9.graph.debugColor, 0.5);
                        for each (_local14 in _local9.buildings) {
                            _local6.moveTo(_local12.x, _local12.y);
                            _local18 = _local14.getHotspots();
                            for each (_local19 in _local18) {
                                _local17 = IsoMath.tilePosToPixelPos(_local19.x, _local19.y);
                                _local6.lineTo(_local17.x, _local17.y);
                            };
                        };
                    };
                    _local8++;
                };
                _local7++;
            };
        }

    }
}//package Classes.sim 
